package com.hr.filter;

import com.hr.utils.JwtUtils;
import com.hr.utils.UserContext;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.util.StringUtils;

import java.io.IOException;

@WebFilter(filterName = "GloubalFilter", urlPatterns = "/*",asyncSupported = true)
@Slf4j
public class GloubalFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.转换为HttpServletRequest和HttpServletResponse
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //2.获取登陆路径
        String loginPath = request.getRequestURI();
        //判断是不是登录请求，如果是登陆请求，则不进行过滤，放行
        if (loginPath.contains("login")||loginPath.contains("/admin/user/add")){
            System.out.println("登录请求,放行");
            filterChain.doFilter(request, response);
            return;
        }
        // 3. 获取 Authorization 头
        String authHeader = request.getHeader("Authorization");
        if (!StringUtils.hasLength(authHeader) || !authHeader.startsWith("Bearer ")) {
            log.warn("Authorization 头缺失或格式错误: {}", authHeader);
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"msg\":\"未登录或 token 缺失\"}");
            return;
        }

        String jwt = authHeader.substring(7); // 去掉 "Bearer " 前缀

        //4.判断token是否过期，如果过期，则返回错误信息（401）
        if (JwtUtils.isTokenExpired(jwt)){
            log.info("令牌已过期, 返回错误结果");
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
        }

        // 5. 解析 token
        try {
            Claims claims = JwtUtils.parseJwt(jwt);
            Long userId = claims.get("userId", Long.class);
            Integer roleId = claims.get("roleId", Integer.class);

            if (userId == null || roleId == null) {
                log.warn("Token 中缺少必要字段: userId 或 roleId");
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"msg\":\"无效的用户信息\"}");
                return;
            }

            // 6. 设置到 UserContext
            UserContext.setUserId(userId);
            UserContext.setRoleId(roleId);
            log.info("用户上下文已设置 - userId: {}, roleId: {}", userId, roleId);

        } catch (Exception e) {
            log.error("解析 Token 失败", e);
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"msg\":\"非法 Token\"}");
            return;
        }


         try {
             log.info("收到请求: {}, URI: {}", request.getMethod(), request.getRequestURI());
            // 7. 放行，执行后续逻辑
            filterChain.doFilter(request, response);
        } finally {
            // 8. 必须清除！防止内存泄漏和线程复用问题
            UserContext.remove();
            log.info("请求结束，已清除 UserContext");
        }
    }
}
